#include "smart_test.h"
#include "dht11_device.h"
#include <stdio.h>
#include "oled_device.h"
#include "esp8266_device.h"
#include <string.h>
#include "led_device.h"
#include "input_key.h"
#include "input_sys.h"
#include "input_net.h"
#include "led_device.h"
#include "fan_device.h"
#include "input_queue.h"
#include "mq2_device.h"
#include "beep_device.h"
#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"
#include "semphr.h"
#include "driver_myrtc.h"
#include "sg90_device.h"
#include "driver_sg90.h"
#include "input_voice.h"
#include "driver_uart.h"
#include "driver_oled.h"
#include "driver_iwdg.h"


static volatile pFanDevice fan;
static volatile pLedDevice led1;
static volatile pLedDevice led2;
static volatile pDHT11Dev dht11;
static volatile pBeepDevice beep;
static volatile pMQ2Dev mq2;
static volatile pNetDevice esp8266;
static volatile pSg90Device sg90;
volatile pDisplayDevice oled;

static int sbuf[6] = {0xAA, 0x55, 0x32, 0x00, 0x55, 0xAA};
static int ipBuf[6] = {0xAA, 0x55, 0x81, 0x00, 0x55, 0xAA};
static int portBuf[6] = {0xAA, 0x55, 0x83, 0x00, 0x55, 0xAA};

extern SemaphoreHandle_t xSemaphore;


void IwdgMonitor(void *arg)
{
    if(__HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST) != RESET)
    {
        printf("IWDG RESET ......\r\n");   
        __HAL_RCC_CLEAR_RESET_FLAGS();    
    }else{
        printf("EXTI RESET ......\r\n");   
    }
//    Driver_IWDG_Init();
    while(1)
    {    
        IWDG_Feed();     
        vTaskDelay(15000);    
    }
}


static int SmartSystemInit(void)
{
    InputQueueInit();
    InputDevAdd();
    
    fan = GetFanDevice("FAN");
    fan->Init(fan);
    
    sg90 = GetSg90Device("SG90");
    sg90->Init(sg90);
    
    led1 = GetLedDevice("LED_BLUE");
    led2 = GetLedDevice("LED_YELLOW");
    led1->Init(led1);
    led2->Init(led2);    
    
    oled = GetOLEDDevice("OLED");
    oled->Init(oled);
    oled->Clear(oled);   
    
    esp8266 = GetNetDev("ESP8266");
    esp8266->Init(esp8266);
    
    printf("Devices Init Complete\r\n");
    return PDSUCCESS;
}


static int DisplayNetAddr(void)
{
    char ip[32] = {0};
    char disip[32] = {0};
    char disport[32] = {0};
    pNetDevice esp8266 = GetNetDev("ESP8266");
    printf("Start Wifi Connecting......\r\n");
    while(esp8266->Connect(esp8266) != PDSUCCESS)
     {
        HAL_Delay(1000);
     }
    printf("Wifi Connet Ok\r\n");
     
    esp8266->Close(esp8266);
    if(esp8266->Transfer(esp8266) == PDSUCCESS)
    {
        printf("Creat UDP Success\r\n");
    }else{
        printf("Creat UDP Fail\r\n");
        return PDFAIL;
    }   

    if(esp8266->GetInfo(esp8266, ip) == PDSUCCESS)
    {
        printf("IP:%s, Port:%s\r\n", ip, ESP8266PORT); 
    }else{
        printf("GetInfo Fail\r\n"); 
        return PDFAIL;
    }
    

    pDisplayDevice oled = GetOLEDDevice("OLED");
    sprintf(disip, "IP:%s",ip);
    oled->Display(oled, 2, 0, disip);
    sprintf(disport, "PORT:%s",ESP8266PORT);
    oled->Display(oled, 4, 0, disport);
    
    printf("Display Addr Complete\r\n");
    return PDSUCCESS;
}    


void GetNetTime(void *arg)
{  
    int tFlag = 0;
    int subFlag = 0;
    unsigned int pre;
    unsigned int cur;
    
    NetTime realTime = {0};
    
    SmartSystemInit();
    DisplayNetAddr();

    RTC_Timer_Init();
    
    pre = HAL_GetTick();
    while(1)
    {
       cur = HAL_GetTick();
       if((cur-pre) > 6000000)
       {
            pre = cur;
            subFlag = 1;
            if(cur == 0xFFFFFFFF)
            {
                pre = 0;
            }
       }
       if((subFlag == 1) || (tFlag == 0))
       {     
            subFlag = 0;
            tFlag = 1;
            while(esp8266->GetNetTime(esp8266, &realTime) != PDSUCCESS);
            RTC_Set_Time(&realTime);
           
       }
       xSemaphoreTake(xSemaphore, portMAX_DELAY);
//       vTaskSuspendAll();
       RTC_Get_Time();
//       xTaskResumeAll(); 
       xSemaphoreGive(xSemaphore); 
       
       vTaskDelay(950);
    }   
}


void GetDht11Value(void *arg)
{  
    char bufinfo[32] = {0};
    dht11 = GetDHT11Device("DHT11");
    dht11->Init(dht11);
 
    while(1)
    {      
         xSemaphoreTake(xSemaphore, portMAX_DELAY);
//        vTaskSuspendAll();
        dht11->GetValue(dht11);
        sprintf(bufinfo, "T: %d , H: %d", dht11->value.temperature, dht11->value.humidity);
        oled->Display(oled, 0, 0, bufinfo);   
//        xTaskResumeAll();
         xSemaphoreGive(xSemaphore); 
        
        vTaskDelay(10000);
    }
}


void GetMq2Value(void *arg)
{
  
   uint16_t pData = 0;      
   double mq2Value = 0; 
//   char mqbuf[32] = {0};
   mq2 = GetMQ2Device("MQ2");
   beep = GetBeepDevice("BEEP");
   beep->Init(beep); 
   mq2->Init(mq2);
    
   xSemaphoreTake(xSemaphore, portMAX_DELAY);
//   vTaskSuspendAll(); 
   mq2->GetValue(mq2, (uint32_t*)&pData, 1); 
//   xTaskResumeAll(); 
   xSemaphoreGive(xSemaphore); 
    
   while(1)
   {   
      mq2Value = pData*3.3/4095;
//      printf("value: %lf\r\n", mq2Value);
      
//      sprintf(mqbuf, "Vc: %.2lf ppm", mq2Value);
//      oled->Display(oled, 6, 0, mqbuf);
      if(mq2Value > 2.0)
       {
            beep->Ctrl(beep, BEEP_ON);
            USART2_SendBytes(sbuf, 6);
       }else{
            beep->Ctrl(beep, BEEP_OFF);
       }
        vTaskDelay(5000);    
    }
}


static void GetEvent(void)
{
    inputEvent event;
    if(GetInputEvent(&event) == PDSUCCESS)
    {
        if(event.iType == Type_Key)
        {
            if(event.iKey_numb ==  K1_NUMB)
            {
                led1->Ctrl(led1, 2);
            }
            else if(event.iKey_numb ==  K2_NUMB)
            {
                led2->Ctrl(led2, 2);
            }    
        }
    
        else if(event.iType == Type_Net)
        {
            if(strcmp(event.str,"LED1-ON") == 0)
            {   
                led1->Ctrl(led1, LED_ON);
            }
            else if(strcmp(event.str,"LED1-OFF") == 0)
            {
                led1->Ctrl(led1, LED_OFF); 
            }
            else if(strcmp(event.str,"LED2-ON") == 0)
            {
                led2->Ctrl(led2, LED_ON); 
            }
            else if(strcmp(event.str,"LED2-OFF") == 0)
            {
                led2->Ctrl(led2, LED_OFF); 
            }
            else if(strcmp(event.str,"FAN-ON") == 0)
            {
                fan->Ctrl(fan, FAN_ON); 
            }
            else if(strcmp(event.str,"FAN-OFF") == 0)
            {
                fan->Ctrl(fan, FAN_OFF); 
            }
            else if(strcmp(event.str,"CUR-FULL") == 0)
            {
                sg90->Ctrl(sg90, SG90_FULL); 
            }
            else if(strcmp(event.str,"CUR-HALF") == 0)
            {
                sg90->Ctrl(sg90, SG90_HALF);
            }
            else if(strcmp(event.str,"CUR-CLOSE") == 0)
            {
                sg90->Ctrl(sg90, SG90_CLOSE);
            }
            else if(strcmp(event.str,"GO-IN") == 0)
            {
                led1->Ctrl(led1, LED_ON);
                led2->Ctrl(led2, LED_ON);  
                fan->Ctrl(fan, FAN_ON);
                sg90->Ctrl(sg90, SG90_HALF);                
            }
            else if(strcmp(event.str,"GO-OUT") == 0)
            {
                led1->Ctrl(led1, LED_OFF);
                led2->Ctrl(led2, LED_OFF);  
                fan->Ctrl(fan, FAN_OFF);  
                sg90->Ctrl(sg90, SG90_CLOSE);  
            }   
        } 
            
        else if(event.iType == Type_Voice)
        {
            if(event.sVal == HOME_MODE)
            {
                led1->Ctrl(led1, LED_ON);
                led2->Ctrl(led2, LED_ON);
                fan->Ctrl(fan, FAN_ON);
                sg90->Ctrl(sg90, SG90_HALF);   
            }
            else if(event.sVal == SAVE_MODE)
            {
                led1->Ctrl(led1, LED_OFF);
                led2->Ctrl(led2, LED_OFF);
                fan->Ctrl(fan, FAN_OFF);
            }
            else if(event.sVal == LIGHT_MODE)
            {
                sg90->Ctrl(sg90, SG90_FULL);
            }
            else if(event.sVal == NORMAL_MODE)
            {
               sg90->Ctrl(sg90, SG90_HALF);
            }
            else if(event.sVal == SLEEP_MODE)
            {
               sg90->Ctrl(sg90, SG90_CLOSE);
               led1->Ctrl(led1, LED_OFF);
               led2->Ctrl(led2, LED_OFF);
               fan->Ctrl(fan, FAN_OFF);      
            } 
            else if(event.sVal == TON_FAN)
            {
               fan->Ctrl(fan, FAN_ON);
            }
            else if(event.sVal == TOF_FAN)
            {
               fan->Ctrl(fan, FAN_OFF);
            }
            else if(event.sVal == TON_LED1)
            {
               led1->Ctrl(led1, LED_ON);
            }
            else if(event.sVal == TOF_LED1)
            {
               led1->Ctrl(led1, LED_OFF);
            }
            else if(event.sVal == TON_LED2)
            {
               led2->Ctrl(led2, LED_ON);
            }
            else if(event.sVal == TOF_LED2)
            {
               led2->Ctrl(led2, LED_OFF);
            } 
            else if(event.sVal == ESPIP)
            {
               USART2_SendBytes(ipBuf, 6);
            } 
            else if(event.sVal == ESPPORT)
            {
               USART2_SendBytes(portBuf, 6);
            }            
        } 
    }
}


void SmartCtrl(void *arg)
{  
    InputDevInit();
    
    while (1)
    {
        GetEvent();
    }
}

